using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using System.Threading;

namespace PureRobot.Digi.ConnectME.JumpStart.LightFun
{
    class Lights: IDisposable
    {
        //Array of output ports to control the LEDs.
        OutputPort[] leds = new OutputPort[5];

        /// <summary>
        /// The direction to sweep across the lights, switching each on and off in turn.
        /// </summary>
        public enum SweepDirection
        {
            /// <summary>
            /// Sweep left.
            /// </summary>
            Left,
            /// <summary>
            /// Sweep right.
            /// </summary>
            Right,
        }

        /// <summary>
        /// Enumeration of the LEDs on the Digi Connect ME JumpStart kit.
        /// </summary>
        public enum Led : int
        {
            /// <summary/>
            One,
            /// <summary/>
            Two,
            /// <summary/>
            Three,
            /// <summary/>
            Four,
            /// <summary/>
            Five,
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="Lights"/> class.
        /// </summary>
        public Lights()
        {
            leds[0] = new OutputPort(RealGpioPins.Gpio1, false);
            leds[1] = new OutputPort(RealGpioPins.Gpio2, false);
            leds[2] = new OutputPort(RealGpioPins.Gpio3, false);
            leds[3] = new OutputPort(RealGpioPins.Gpio4, false);
            leds[4] = new OutputPort(RealGpioPins.Gpio5, false);
        }

        /// <summary>
        /// Switches on the given led.
        /// </summary>
        public void SwitchOn(Led led)
        {
            leds[(int)led].Write(true);
        }
        
        /// <summary>
        /// Switches off the given led.
        /// </summary>
        public void SwitchOff(Led led)
        {
            leds[(int)led].Write(false);
        }

        /// <summary>
        /// Switches all the lights on.
        /// </summary>
        public void SwitchAllOn()
        {
            for (int led = 0; led < leds.Length; led++)
            {
                leds[led].Write(true);
            }
        }

        /// <summary>
        /// Switches all the lights off.
        /// </summary>
        public void SwitchAllOff()
        {
            for (int led = 0; led < leds.Length; led++)
            {
                leds[led].Write(false);
            }
        }

        /// <summary>
        /// Sweeps across the LEDs, setting high for the specified millisecond delay travelling in the given sweep direction.
        /// </summary>
        /// <param name="millisecondDelay">The millisecond delay.</param>
        /// <param name="sweepDirection">The sweep direction.</param>
        public void Sweep(int millisecondDelay, SweepDirection sweepDirection)
        {
            switch (sweepDirection)
            {
                case SweepDirection.Left:
                    {
                        for (int led = 0; led < leds.Length; led++)
                        {
                            blinkLight(led, millisecondDelay);
                        }
                        break;
                    }
                case SweepDirection.Right:
                    {
                        for (int led = leds.Length-1; led >= 0; led--)
                        {
                            blinkLight(led, millisecondDelay);
                        }
                        break;
                    }
            }            
        }

        private void blinkLight(int led, int millisecondDelay)
        {
            leds[led].Write(true);
            Thread.Sleep(millisecondDelay);
            leds[led].Write(false);
        }

        #region IDisposable Members

        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        public void Dispose()
        {
            for (int led = 0; led < leds.Length; led++)
            {
                if (leds[led] != null)
                {
                    leds[led].Dispose();
                    leds[led] = null;
                }
            }
        }
        #endregion
    }
}
